package com.toannv.handler;

import java.util.List;
import java.util.Stack;

import com.smartfoxserver.v2.entities.Room;
import com.smartfoxserver.v2.entities.User;
import com.smartfoxserver.v2.entities.data.ISFSObject;
import com.smartfoxserver.v2.entities.data.SFSObject;
import com.smartfoxserver.v2.extensions.BaseClientRequestHandler;
import com.toannv.card.card;
import com.toannv.definitions.KeyObjectId;
import com.toannv.definitions.RequestId;
import com.toannv.definitions.ResponseId;
import com.toannv.extension.RoomExtension;
import com.toannv.gameController.CheckPhom;
import com.toannv.gameController.EndGame;
import com.toannv.helper.Roomhelper;

public class HaPhomHandler extends BaseClientRequestHandler{

	@Override
	public void handleClientRequest(User sender, ISFSObject paras) {
		// TODO Auto-generated method stub
		int idSender = sender.getPlayerId();
		
		if(idSender==RoomExtension.haPhomid){
			int soPhom = paras.getInt(KeyObjectId.SO_PHOM);
			
			Room CurrentRoom = Roomhelper.getCurrentRoom(this);
			List<User> users = CurrentRoom.getUserList();
			
			SFSObject message_endGame = new SFSObject();
			
			SFSObject HaPhomObject = new SFSObject();
			
			if(soPhom == 0){
				send(ResponseId.MOM, HaPhomObject, users);
				nextStep(RoomExtension.NumberOfPlayers, idSender, message_endGame, users);
			}
			
			HaPhomObject.putInt(KeyObjectId.SO_PHOM, soPhom);
			
			card CardPhom[][];
			CardPhom = new card[soPhom][];
			for(int i=0; i<soPhom; i++){
				int soQuanCuaMotPhom = paras.getInt(KeyObjectId.SO_QUAN_CUA_PHOM + i);
				
				HaPhomObject.putInt(KeyObjectId.SO_QUAN_CUA_PHOM + i, soQuanCuaMotPhom);
				
				CardPhom[i] = new card[soQuanCuaMotPhom];
				if(i==0){
					for(int j=0; j<soQuanCuaMotPhom;j++){
						int number = paras.getInt(KeyObjectId.DIEM_PHOM_MOT + j);
						int poker = paras.getInt(KeyObjectId.CHAT_PHOM_MOT + j);
						
						HaPhomObject.putInt(KeyObjectId.DIEM_PHOM_MOT + j, number);
						HaPhomObject.putInt(KeyObjectId.CHAT_PHOM_MOT + j, poker);
						
						CardPhom[i][j] = new card(number, poker);
					}
				}
				else if(i==1){
					for(int j=0; j<soQuanCuaMotPhom;j++){
						int number = paras.getInt(KeyObjectId.DIEM_PHOM_HAI + j);
						int poker = paras.getInt(KeyObjectId.CHAT_PHOM_HAI + j);
						
						HaPhomObject.putInt(KeyObjectId.DIEM_PHOM_HAI + j, number);
						HaPhomObject.putInt(KeyObjectId.CHAT_PHOM_HAI + j, poker);
						
						CardPhom[i][j] = new card(number, poker);
					}
				}
				else if(i==2){
					for(int j=0; j<soQuanCuaMotPhom;j++){
						int number = paras.getInt(KeyObjectId.DIEM_PHOM_BA + j);
						int poker = paras.getInt(KeyObjectId.CHAT_PHOM_BA + j);
						
						HaPhomObject.putInt(KeyObjectId.DIEM_PHOM_BA + j, number);
						HaPhomObject.putInt(KeyObjectId.CHAT_PHOM_BA + j, poker);
						
						CardPhom[i][j] = new card(number, poker);
					}
				}
			}
			
			Stack<card> testStack = new Stack<card>();
			
			if(idSender==0){
				testStack = extracted(RoomExtension.CardOfUser0Eat);
			}
			else if(idSender==1){
				testStack = extracted(RoomExtension.CardOfUser1Eat);
			}
			else if(idSender==2){
				testStack = extracted(RoomExtension.CardOfUser2Eat);
			}
			else if(idSender==3){
				testStack = extracted(RoomExtension.CardOfUser3Eat);
			}
			
			
			int checkphom = checkPhomVaBaiDaAn(testStack, CardPhom);
			
			
			
			if(checkphom == 3){
				send(ResponseId.HA_PHOM_OK, HaPhomObject, users);
				
				nextStep(RoomExtension.NumberOfPlayers, idSender, message_endGame, users);
			}
			else if(checkphom == 1){
				send(ResponseId.AN_LAO, HaPhomObject, users);
				nextStep(RoomExtension.NumberOfPlayers, idSender, message_endGame, users);
			}
			else if(checkphom == 2){
				send(ResponseId.AN_HAI_QUAN_MOT_PHOM, HaPhomObject, users);
				nextStep(RoomExtension.NumberOfPlayers, idSender, message_endGame, users);
			}
			else if(checkphom == 0){
				send(ResponseId.KHONG_PHAI_PHOM, HaPhomObject, sender);
				send(ResponseId.HA_PHOM, message_endGame, sender);
				RoomExtension.haPhomid = idSender;
			}
		}
	}
	
	@SuppressWarnings("unchecked")
	private static Stack<card> extracted(Stack<card> Cards) {
		return (Stack<card>) Cards.clone();
	}
	
	private void nextStep(int numberOfPlayer, int idSender, SFSObject message_endGame, List<User> users){
		if(EndGame.isFinish(numberOfPlayer)){
			endgame();
		}
		else{
			//Gửi cho người chơi trong phòng biết id của người sẽ bốc hoặc ăn bài
			SFSObject sfsO = new SFSObject();
			sfsO.putInt(KeyObjectId.BOC_HOAC_AN_BAI_ID, (idSender+1) % (RoomExtension.NumberOfPlayers));
			RoomExtension.UserRunning = (idSender+1) % (RoomExtension.NumberOfPlayers);
			send(RequestId.BOC_HOAC_AN_BAI, sfsO, users);
		}
	}
	
	//Tính điểm, ghi lại các vết gửi cho người chơi
	private void endgame(){
		
	}
	
	private int checkPhomVaBaiDaAn(Stack<card> Cards, card[][] Phom) {
		for(int i=0; i<Phom.length;i++){
			if(CheckPhom.checkDoc(Phom[i]) || CheckPhom.checkNgang(Phom[i])){
				continue;
			}
			else return 0;
		}
		
		position po[] = new position[Cards.size()];
		int element = 0;
		while(!Cards.isEmpty()){
			card cardEated = Cards.pop();
			int exist = 0;
			for(int i=0; i<Phom.length;i++){
				for(int j=0; j<Phom[i].length;j++){
					if(cardEated.compare(Phom[i][j])){
						po[element] = new position(i, j);
						exist = 1;
					}
				}
			}
			
			if(exist == 0){
				return 1;
			}
		}
		
		if(po.length==1){
			return 3;
		}
		
		else if(po.length==2){
			if(po[0].compare(po[1])){
				return 2;
			}
			else return 3;
		}
		
		else if(po.length==3){
			if(po[0].compare(po[1]) || po[0].compare(po[2]) || po[1].compare(po[2])){
				return 2;
			}
			return 3;
		}
		
		return 3;
	}
}

class position{
	private int x;
	private int y;
	
	public position(){
		this.x = 0;
		this.y = 0;
	}
	
	public position(int X, int Y){
		this.x = X;
		this.y = Y;
	}
	
	public void setX(int X){
		this.x = X;
	}
	
	public void setY(int Y){
		this.y = Y;
	}
	
	public int getX(){
		return x;
	}
	
	public int getY(){
		return y;
	}
	
	public boolean compare(position Other){
		if(this.x == Other.getX() && this.y == Other.getY()){
			return true;
		}
		
		return false;
	}
}
